home *** CD-ROM | disk | FTP | other *** search
- /********************************************************\
- * *
- * NNTP local Macintosh Server. *
- * *
- /********************************************************/
-
- #include "NNTP Server.h"
- #include <stdio.h>
- #include <string.h>
-
- short netNewsDrive; /* Drive # of NetNews drive */
- char netNewsVolName[32]; /* Volume name of NetNews data */
- short netNewsVRefNum; /* Volume reference # */
- char PathTransFSpec[256]; /* Path translation FSpec */
- char activeFSpec[256]; /* Active file FSpec */
- char CurrentGroupFSpec[256]; /* Dir FSpec of current group */
- char lastGroup[256] = "none "; /* Last canonical group selected */
- char lastISOgroup[256]; /* Last ISO group selected */
- char lastActiveEntry[256] = "none "; /* Last entry from Active file */
- int TCP_DriverRefNum; /* MacTCP Driver reference number */
- TCPiopb NNTP_PB;
- EventRecord evt;
- char msgText[100];
- WDS sendWDS;
- Boolean running, gWNEImplemented, sessionActive;
- EventRecord gTheEvent;
- MenuHandle gAppleMenu, gFileMenu, gEditMenu;
- WindowPtr myWindow;
- Rect aRect;
- Rect *rectPtr;
- char rcvBuf[RCV_BUF_SIZE];
- char xmtBuf[XMT_BUF_SIZE];
- unsigned short bufLen;
-
- /***************************************************************************\
- * *
- * Routine: main *
- * *
- * Function: Initialize the server and begin executing the main loop. *
- * *
- * Inputs: None *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- main()
- {
- ToolBoxInit();
- MenuBarInit();
- TCPInit();
- MainLoop();
- }
-
- /***************************************************************************\
- * *
- * Routine: MainLoop *
- * *
- * Function: Establish a client connection and service requests. *
- * Continue until the user 'Quit's. *
- * *
- * Inputs: None *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- MainLoop()
- {
- running = TRUE;
- while (running)
- {
- while (running)
- {
- PassiveOpen(&NNTP_PB, NNTP_SERVER);
- sessionActive = FALSE;
- while ((NNTP_PB.ioResult == inProgress) && running)
- {
- HandleEvent();
- }
- if (NNTP_PB.ioResult == noErr)
- {
- strcpy(rcvBuf, "INIT\r\n");
- sessionActive = TRUE;
- }
- while (sessionActive && running)
- {
- HandleEvent();
- if (NNTP_PB.ioResult == noErr)
- {
- bufLen = NNTP_PB.csParam.receive.rcvBuffLen;
- ProcessBuffer((char *)&rcvBuf, bufLen);
- ReceiveTCP(&NNTP_PB, rcvBuf, RCV_BUF_SIZE);
- }
- if (TCPStatusCheck(NNTP_PB.tcpStream) != ESTABLISHED)
- {
- CleanUp();
- sessionActive = FALSE;
- }
- }
- }
- }
- CleanUp();
- ExitToShell();
- }
-
- /***************************************************************************\
- * *
- * Routine: ProcessBuffer *
- * *
- * Function: Process a buffer that may contain one or more NNTP *
- * requests. *
- * *
- * Inputs: Pointer to receive buffer, and length of buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- ProcessBuffer(buf, len)
- char *buf;
- unsigned short len;
- {
- char *src, *dst;
- char cmdBuf[512];
- short spaceFound;
-
- src = buf;
- dst = buf;
- buf[len] = 0;
- spaceFound = FALSE;
- while(*src != 0)
- {
- if ((*src == SPACE) || (*src == TAB))
- {
- spaceFound = TRUE;
- }
- if (spaceFound)
- {
- *dst++ = *src++;
- }
- else
- {
- *dst++ = toupper(*src++);
- }
- }
- while (strlen(buf) > 1)
- {
- GetRequest(buf, cmdBuf);
- ProcessRequest(cmdBuf);
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: GetRequest *
- * *
- * Function: Return a request line from request buffer. *
- * *
- * *
- * Inputs: Pointer to receive buffer and cmdBuf. *
- * *
- * Outputs: Adjusted buffer data and modified length. *
- * *
- \***************************************************************************/
-
- GetRequest(buf, cmdBuf)
- char *buf, *cmdBuf;
- {
- char *src, *dst;
-
- src = buf;
- dst = cmdBuf;
- while((*src != 0) && (*src != LF))
- {
- *dst++ = *src++;
- }
- *dst++ = *src++; /* LF */
- *dst = 0;
-
- dst = buf;
- while(*src != 0)
- {
- *dst++ = *src++;
- }
- *dst = 0;
- }
-
- /***************************************************************************\
- * *
- * Routine: ProcessRequest *
- * *
- * Function: Process the following NNTP requests: *
- * *
- * INIT *
- * ARTICLE *
- * BODY *
- * GROUP *
- * HEAD *
- * HELP *
- * IHAVE *
- * LAST *
- * LIST *
- * NEWGROUPS *
- * NEWNEWS *
- * NEXT *
- * POST *
- * QUIT *
- * SLAVE *
- * STAT *
- * X... - Extensions *
- * *
- * Inputs: Pointer to receive buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- ProcessRequest(cmdBuf)
- char *cmdBuf;
- {
- if (memcmp("INIT", cmdBuf, strlen("INIT")) == 0)
- {
- if (!InitServer())
- {
- CleanUp();
- sessionActive = FALSE;
- }
- }
-
- if (memcmp("ARTICLE", cmdBuf, strlen("ARTICLE")) == 0)
- {
- ArticleCmd(cmdBuf);
- }
-
- if (memcmp("BODY", cmdBuf, strlen("BODY")) == 0)
- {
- BodyCmd(cmdBuf);
- }
-
- if (memcmp("GROUP", cmdBuf, strlen("GROUP")) == 0)
- {
- GroupCmd(cmdBuf);
- }
-
- if (memcmp("HEAD", cmdBuf, strlen("HEAD")) == 0)
- {
- HeadCmd(cmdBuf);
- }
-
- if (memcmp("HELP", cmdBuf, strlen("HELP")) == 0)
- {
- HelpCmd(cmdBuf);
- }
-
- if (memcmp("IHAVE", cmdBuf, strlen("IHAVE")) == 0)
- {
- IhaveCmd(cmdBuf);
- }
-
- if (memcmp("LAST", cmdBuf, strlen("LAST")) == 0)
- {
- LastCmd(cmdBuf);
- }
-
- if (memcmp("LIST", cmdBuf, strlen("LIST")) == 0)
- {
- ListCmd(cmdBuf);
- }
-
- if (memcmp("NEWGROUPS", cmdBuf, strlen("NEWGROUPS")) == 0)
- {
- NewGroupsCmd(cmdBuf);
- }
-
- if (memcmp("NEWNEWS", cmdBuf, strlen("NEWNEWS")) == 0)
- {
- NewNewsCmd(cmdBuf);
- }
-
- if (memcmp("NEXT", cmdBuf, strlen("NEXT")) == 0)
- {
- NextCmd(cmdBuf);
- }
-
- if (memcmp("POST", cmdBuf, strlen("POST")) == 0)
- {
- PostCmd(cmdBuf);
- }
-
- if (memcmp("QUIT", cmdBuf, strlen("QUIT")) == 0)
- {
- QuitCmd(cmdBuf);
- }
-
- if (memcmp("SLAVE", cmdBuf, strlen("SLAVE")) == 0)
- {
- SlaveCmd(cmdBuf);
- }
-
- if (memcmp("STAT", cmdBuf, strlen("STAT")) == 0)
- {
- StatCmd(cmdBuf);
- }
-
- if (memcmp("X", cmdBuf, strlen("X")) == 0)
- {
- XCmd(cmdBuf);
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: InitServer *
- * *
- * Function: Initialize the server. *
- * *
- * Inputs: None *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- InitServer()
- {
- long freeBytes;
- OSErr status, searching, found;
-
- searching = TRUE;
- netNewsDrive = 0;
- searching = TRUE;
- found = FALSE;
- while (searching)
- {
- status = GetVInfo(netNewsDrive, netNewsVolName, &netNewsVRefNum, &freeBytes);
- if (netNewsDrive < MAX_DRIVES)
- {
- PtoCstr(netNewsVolName);
- if ((memcmp("NETNEWS", netNewsVolName, strlen("NETNEWS")) == 0))
- {
- searching = FALSE;
- found = TRUE;
- }
- else
- {
- netNewsDrive++;
- }
- }
- else
- {
- searching = FALSE;
- }
- }
- if (found)
- {
- strcpy(xmtBuf, "201 NetNews/CD NNTP Mac Server - (no posting).\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
-
- strcpy (PathTransFSpec, netNewsVolName);
- strcat (PathTransFSpec, ":LIB:PATHTRAN.;1");
-
- strcpy (activeFSpec, netNewsVolName);
- strcat (activeFSpec, ":LIB:ACTIVE.;1");
- return TRUE;
- }
- else
- {
- strcpy(msgText, "NetNews/CD Server: Can't find NETNEWS_CD volume.");
- Report(msgText);
- while (!Button())
- {
- WaitNextEvent( everyEvent, &gTheEvent, 0L, 0L);
- }
- strcpy(xmtBuf, "503 NetNews/CD Server: Can't find NETNEWS_CD volume.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- return FALSE;
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: OpenMsgFile *
- * *
- * Function: Open a message file. If the file "xxx.;1" is not found, *
- * look for a file named "xxx.XRF;1 and use it as a pointer *
- * to the actual message file. This supports articles that *
- * are posted to multiple groups (without duplicating the *
- * article text). *
- * *
- * Inputs: Article path and open mode. *
- * *
- * Outputs: Returns file reference if found, zero if not found. *
- * *
- \***************************************************************************/
-
- OpenMsgFile(path, mode, msgFile)
- char *path;
- char *mode;
- FILE **msgFile;
- {
- char altPath[256], line[256];
- short pathLength, lineLength;
- FILE *xrfFile;
-
- *msgFile = fopen(path, mode);
- if (*msgFile)
- {
- return;
- }
- else
- {
- pathLength = strlen(path);
- strcpy(altPath, path);
- strcpy(&altPath[pathLength-2], "XRF;1");
- xrfFile = fopen(altPath, "r");
- if(xrfFile)
- {
- if (GetLine(xrfFile, line))
- {
- fclose(xrfFile);
- strcpy(altPath, netNewsVolName);
- strcat(altPath, ":SPOOL:");
- lineLength = strlen(line);
- line[lineLength-2] = 0; /* Delete <CR><LF> */
- strcat(altPath, line);
- strcat(altPath, ".;1");
- SlashToColon(altPath);
- *msgFile = fopen(altPath, mode);
- }
- }
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: ArticleCmd *
- * *
- * Function: Respond to an 'ARTICLE' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- ArticleCmd(buf)
- char *buf;
- {
- char msg[16];
- char msgPath[256], filename[32], line[256];
- FILE *msgFile;
- short stillReading;
-
- GetWord(buf, msg, 2);
- strcpy(msgPath, CurrentGroupFSpec);
- strcat(msgPath, ":");
- GetMsgFilename(msg, filename);
- strcat(msgPath, filename);
-
- /* Open the message file and send it to the requestor. */
-
- OpenMsgFile(msgPath, "r", &msgFile);
- if (msgFile)
- {
- strcpy(xmtBuf, "220 <Message-ID???> head and body follow\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- stillReading = true;
- while(stillReading)
- {
- if (GetLine(msgFile, line))
- {
- SendTCP(&NNTP_PB, line, (short)strlen(line));
- }
- else
- {
- stillReading = FALSE;
- }
- }
- fclose(msgFile);
- strcpy(xmtBuf, ".\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- else
- {
- strcpy(xmtBuf, "503 program fault - command not performed\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: BodyCmd *
- * *
- * Function: Respond to an 'BODY' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- BodyCmd(buf)
- char *buf;
- {
- char msg[16];
- char msgPath[256], filename[32], line[256];
- FILE *msgFile;
- short stillReading, bodyFound;
-
- GetWord(buf, msg, 2);
- strcpy(msgPath, CurrentGroupFSpec);
- strcat(msgPath, ":");
- GetMsgFilename(msg, filename);
- strcat(msgPath, filename);
-
- /* Open the message file and send the Body portion to the requestor. */
-
- OpenMsgFile(msgPath, "r", &msgFile);
- if (msgFile)
- {
- strcpy(xmtBuf, "222 ");
- strcat(xmtBuf, msg);
- strcat(xmtBuf, " <Message-ID ???> Article retrieved - body follows.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- stillReading = true;
- bodyFound = false;
- while(stillReading)
- {
- if (GetLine(msgFile, line))
- {
- if (bodyFound)
- {
- SendTCP(&NNTP_PB, line, (short)strlen(line));
- }
- if (strlen(line) < 3)
- {
- bodyFound = true;
- }
- }
- else
- {
- stillReading = FALSE;
- }
- }
- fclose(msgFile);
- strcpy(xmtBuf, ".\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- else
- {
- strcpy(xmtBuf, "503 program fault - command not performed\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: GetActiveEntry *
- * *
- * Function: Locate and return an entry from the 'Active' file for *
- * the requested newsgroup. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- GetActiveEntry(group, entry)
- char *group, *entry;
- {
- FILE *activeFile;
- short stillReading;
- char line[256];
- char lastGroup[256];
- short found;
-
- entry[0] = 0;
- GetWord(lastActiveEntry, lastGroup, 1);
- if (!strcmp (lastGroup, group))
- {
- strcpy(entry, lastActiveEntry);
- return;
- }
- activeFile = fopen(activeFSpec, "r");
- if (activeFile)
- {
- stillReading = TRUE;
- found = FALSE;
- *entry = 0;
- while(stillReading && !found)
- {
- if (GetLine(activeFile, line))
- {
- if (!memcmp(line, group, strlen(group)))
- {
- strcpy(entry, line);
- found = TRUE;
- }
- }
- else
- {
- stillReading = FALSE;
- }
- }
- fclose(activeFile);
- strcpy(lastActiveEntry, entry);
- return found;
- }
- else
- {
- return false;
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: GetGroupInfo *
- * *
- * Function: Format the 'GROUP' request response. *
- * *
- * Inputs: Group requested and response buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- GetGroupInfo(group, groupInfo)
- char *group, *groupInfo;
- {
- char first[16], last[16], msgs[16];
- char activeEntry[256];
- long numFirst, numLast, numMsgs;
- char *ptr;
-
- /* Active file format: "news.admin 00001002 01000 y" */
- /* Reply format: "211 3 01000 00001002 news.admin\r\n" */
-
- if (GetActiveEntry(group, activeEntry))
- {
- GetWord(activeEntry, last, 2);
- GetWord(activeEntry, first, 3);
- numFirst = strtol(first, &ptr, 10);
- numLast = strtol(last, &ptr, 10);
- numMsgs = numLast - numFirst + 1;
- sprintf (msgs, "%ld", numMsgs);
- sprintf (first, "%ld", numFirst);
- sprintf (last, "%ld", numLast);
- RememberGroup(group);
-
- strcpy(groupInfo, "211 ");
- strcat(groupInfo, msgs);
- strcat(groupInfo, " ");
- strcat(groupInfo, first);
- strcat(groupInfo, " ");
- strcat(groupInfo, last);
- strcat(groupInfo, " ");
- strcat(groupInfo, group);
- strcat(groupInfo, "\r\n");
- return true;
- }
- else
- {
- return false;
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: SlashToColon *
- * *
- * Function: Change all occurances of '/' to ':' for Macintosh style *
- * folder heirarchy paths. *
- * *
- * Inputs: Word to be scanned. *
- * *
- * Outputs: Updated word. *
- * *
- \***************************************************************************/
-
- SlashToColon(word)
- char *word;
- {
- short i;
- char *src;
-
- src = word;
- for(i=0; i<strlen(word); i++)
- {
- if (*src == '/')
- {
- *src = ':';
- }
- src++;
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: TranslateGroup *
- * *
- * Function: Use the 'Pathtran' file to translate the Unix group name *
- * to the ISO filename. *
- * *
- * Inputs: Group *
- * *
- * Outputs: CurrentGroupFSpec *
- * *
- \***************************************************************************/
-
- TranslateGroup(group, isoName)
- char *group, *isoName;
- {
- FILE *transFile;
- short stillReading;
- char line[256];
-
- if (!strcmp(lastGroup, group))
- {
- strcpy(isoName, lastISOgroup);
- return;
- }
-
- transFile = fopen(PathTransFSpec, "r");
- if (transFile)
- {
- stillReading = true;
- *isoName = 0;
- while(stillReading)
- {
- if (GetLine(transFile, line))
- {
- if (!memcmp(line, group, strlen(group)))
- {
- GetWord(line, isoName, 2);
- SlashToColon(isoName);
- stillReading = FALSE;
- }
- }
- else
- {
- stillReading = FALSE;
- }
- }
- fclose(transFile);
- strcpy(lastISOgroup, isoName);
- }
- else
- {
- strcpy(xmtBuf, "503 program fault - command not performed\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: RememberGroup *
- * *
- * Function: Remember which group is current. *
- * *
- * Inputs: Group *
- * *
- * Outputs: CurrentGroupFSpec *
- * *
- \***************************************************************************/
-
- RememberGroup(group)
- char *group;
- {
- char isoName[256];
-
- strcpy(CurrentGroupFSpec, netNewsVolName);
- strcat(CurrentGroupFSpec, ":SPOOL:");
- TranslateGroup(group, isoName);
- strcat(CurrentGroupFSpec, isoName);
- strcpy(lastGroup, group);
- }
-
- /***************************************************************************\
- * *
- * Routine: GroupCmd *
- * *
- * Function: Respond to a 'GROUP' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- GroupCmd(buf)
- char *buf;
- {
- char group[256], groupInfo[256];
-
- GetWord(buf, group, 2);
- if (GetGroupInfo(group, groupInfo))
- {
- SendTCP(&NNTP_PB, groupInfo, (short)strlen(groupInfo));
- }
- else
- {
- strcpy(xmtBuf, "411 no such news group\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: HeadCmd *
- * *
- * Function: Respond to a 'HEAD' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- HeadCmd(buf)
- char *buf;
- {
- char msg[16];
- char msgPath[256], filename[32], line[256];
- FILE *msgFile;
- short stillReading;
-
- GetWord(buf, msg, 2);
- strcpy(msgPath, CurrentGroupFSpec);
- strcat(msgPath, ":");
- GetMsgFilename(msg, filename);
- strcat(msgPath, filename);
-
- /* Open the message file and send the header portion to the requestor. */
-
- OpenMsgFile(msgPath, "r", &msgFile);
- if (msgFile)
- {
- strcpy(xmtBuf, "221 ");
- strcat(xmtBuf, msg);
- strcat(xmtBuf, " <Message-ID ???> Article retrieved, header follows\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- stillReading = true;
- while(stillReading)
- {
- if (GetLine(msgFile, line))
- {
- if (strlen(line) < 3)
- {
- stillReading = FALSE;
- }
- else
- {
- SendTCP(&NNTP_PB, line, (short)strlen(line));
- }
- }
- else
- {
- stillReading = FALSE;
- }
- }
- fclose(msgFile);
- strcpy(xmtBuf, ".\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- else
- {
- strcpy(xmtBuf, "503 program fault - command not performed\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: HelpCmd *
- * *
- * Function: Respond to a 'HELP' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- HelpCmd(buf)
- char *buf;
- {
- strcpy(xmtBuf, "100 Help text follows.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- strcpy(xmtBuf, "NetNews/CD NNTP Mac Server - (no posting).\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- strcpy(xmtBuf, "Version 1.0\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- strcpy(xmtBuf, ".\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
-
- /***************************************************************************\
- * *
- * Routine: IhaveCmd *
- * *
- * Function: Respond to a 'IHAVE' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- IhaveCmd(buf)
- char *buf;
- {
- strcpy(xmtBuf, "435 - article not wanted, do not send it.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
-
- /***************************************************************************\
- * *
- * Routine: LastCmd *
- * *
- * Function: Respond to a 'LAST' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- LastCmd(buf)
- char *buf;
- {
- strcpy(xmtBuf, "223 - article retrieved - request text seperately.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
-
- /***************************************************************************\
- * *
- * Routine: GetLine *
- * *
- * Function: Reads a line of data from a file. *
- * *
- * Inputs: FILE pointer and input buffer. *
- * *
- * Outputs: A line of data from the specified file. *
- * *
- \***************************************************************************/
-
- GetLine(file, buf)
- FILE *file;
- char *buf;
- {
- short c;
- short validData;
- char *dst;
-
- dst = buf;
- c = fgetc(file);
- if (c == EOF)
- {
- validData = FALSE;
- }
- else
- {
- validData = TRUE;
- }
- while ((c!= EOF) && (c!= LF))
- {
- *dst++ = c;
- c = fgetc(file);
- }
- *dst++ = CR;
- *dst++ = LF;
- *dst++ = 0;
- return validData;
- }
-
- /***************************************************************************\
- * *
- * Routine: ListCmd *
- * *
- * Function: Respond to a 'LIST' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- ListCmd(buf)
- char *buf;
- {
- FILE *activeFile;
- short stillReading;
-
- strcpy(xmtBuf, "215 list of newsgroups follow\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- activeFile = fopen(activeFSpec, "r");
- if (activeFile)
- {
- stillReading = true;
- while(stillReading)
- {
- if (GetLine(activeFile, xmtBuf))
- {
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- else
- {
- stillReading = FALSE;
- }
- }
- fclose(activeFile);
- strcpy(xmtBuf, ".\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- else
- {
- strcpy(xmtBuf, "503 program fault - command not performed\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: NewGroupsCmd *
- * *
- * Function: Respond to a 'NEWGROUPS' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- NewGroupsCmd(buf)
- char *buf;
- {
- strcpy(xmtBuf, "231 list of new newsgroups follows.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- strcpy(xmtBuf, ".\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
-
- /***************************************************************************\
- * *
- * Routine: NewNewsCmd *
- * *
- * Function: Respond to a 'NEWNEWS' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- NewNewsCmd(buf)
- char *buf;
- {
- strcpy(xmtBuf, "230 list of new articles by message-id follows.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- strcpy(xmtBuf, ".\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
-
- /***************************************************************************\
- * *
- * Routine: NextCmd *
- * *
- * Function: Respond to a 'NEXT' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- NextCmd(buf)
- char *buf;
- {
- strcpy(xmtBuf, "223 - article retrieved - request text seperately.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
-
- /***************************************************************************\
- * *
- * Routine: PostCmd *
- * *
- * Function: Respond to a 'POST' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- PostCmd(buf)
- char *buf;
- {
- strcpy(xmtBuf, "440 NetNews NNTP Local Mac Server - posting not allowed.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
-
- /***************************************************************************\
- * *
- * Routine: QuitCmd *
- * *
- * Function: Respond to a 'QUIT' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- QuitCmd(buf)
- char *buf;
- {
- strcpy(xmtBuf, "205 NetNews NNTP Local Mac Server closing connection. Goodbye.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- TerminateSession(NNTP_PB.tcpStream);
- sessionActive = FALSE;
- }
-
- /***************************************************************************\
- * *
- * Routine: SlaveCmd *
- * *
- * Function: Respond to a 'SLAVE' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- SlaveCmd(buf)
- char *buf;
- {
- strcpy(xmtBuf, "202 - slave status noted.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
-
- /***************************************************************************\
- * *
- * Routine: StatCmd *
- * *
- * Function: Respond to a 'STAT' request. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- StatCmd(buf)
- char *buf;
- {
- strcpy(xmtBuf, "223 - article retrieved - request text seperately.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
-
- /***************************************************************************\
- * *
- * Routine: GetMsgFilename *
- * *
- * Function: Convert a message number string to an ISO filename. *
- * *
- * Inputs: Message number (ASCII, possible leading zeros) *
- * *
- * Outputs: ISO filename *
- * *
- \***************************************************************************/
-
- GetMsgFilename(msg, filename)
- char *msg, *filename;
- {
- char *src, *dst;
-
- src = msg;
- dst = filename;
- while ((*src != 0) && (*src == '0'))
- {
- src++;
- }
- while (*src != 0)
- {
- *dst++ = *src++;
- }
- *dst++ = 0;
- strcat(filename, ".;1");
- }
-
- /***************************************************************************\
- * *
- * Routine: GetSubject *
- * *
- * Function: Retrieve the SUBJECT line from a specified message. *
- * *
- * Inputs: Message and subject buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- GetSubject(msg, subject)
- char *msg, *subject;
- {
- char msgPath[256], filename[32], line[256];
- char msgPart[256], *subjMatter;
- FILE *msgFile;
- short stillReading, found;
-
- found = FALSE;
- strcpy(subjMatter, "(None)\r\n");
- strcpy(msgPath, CurrentGroupFSpec);
- strcat(msgPath, ":");
- GetMsgFilename(msg, filename);
- strcat(msgPath, filename);
-
- /* Open the message file and find the SUBJECT line. */
-
- OpenMsgFile(msgPath, "r", &msgFile);
- if (msgFile)
- {
- stillReading = true;
- *subject = 0;
- while(stillReading)
- {
- if (GetLine(msgFile, line))
- {
- GetWord(line, msgPart, 1);
- if (!strcmp (msgPart, "Subject:"))
- {
- strcpy(subjMatter, &line[9]);
- stillReading = FALSE;
- found = TRUE;
- }
- }
- else
- {
- stillReading = FALSE;
- }
- }
- fclose(msgFile);
- }
- strcpy(subject, msg);
- strcat(subject, " ");
- strcat(subject, subjMatter);
- return found;
- }
-
- /***************************************************************************\
- * *
- * Routine: XCmd *
- * *
- * Function: Respond to any Xxxx (extension) request. *
- * XHDR is the only extension supported. *
- * *
- * Inputs: Request buffer. *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- XCmd(buf) /* "XHDR SUBJECT first-last" */
- char *buf;
- {
- long i, cnt, first, last;
- char msg[16], firstLast[32], subject[256];
- char *ptr;
-
- if (memcmp("XHDR SUBJECT", buf, strlen("XHDR SUBJECT")) == 0)
- {
- strcpy(xmtBuf, "221 Subject fields follow.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
-
- GetWord(buf, firstLast, 3);
- first = strtol(firstLast, &ptr, 10);
- ptr++;
- last = strtol(ptr, &ptr, 10);
- if (last < first)
- {
- last = first;
- }
- for(i=first; i<=last; i++)
- {
- sprintf (msg, "%ld", i);
- if (GetSubject(msg, subject))
- {
- SendTCP(&NNTP_PB, subject, (short)strlen(subject));
- }
- }
- strcpy(xmtBuf, ".\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- else
- {
- strcpy(xmtBuf, "500 Command not recognized.\r\n");
- SendTCP(&NNTP_PB, xmtBuf, (short)strlen(xmtBuf));
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: ToolBoxInit *
- * *
- * Function: Macintosh toolbox initialization. *
- * *
- * Inputs: None *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- ToolBoxInit()
- {
- InitGraf( &thePort );
- InitFonts();
- FlushEvents( everyEvent, REMOVE_ALL_EVENTS );
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs( NIL_POINTER );
- InitCursor();
- }
-
- /***************************************************************************\
- * *
- * Routine: MenuBarInit *
- * *
- * Function: Menu Bar initialization. *
- * *
- * Inputs: None *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- MenuBarInit()
- {
- Handle myMenuBar;
-
- if ((myMenuBar = GetNewMBar(BASE_RES_ID)) == NIL_POINTER)
- ErrorHandler(NO_MBAR);
- SetMenuBar(myMenuBar);
- if ((gAppleMenu = GetMHandle(APPLE_MENU_ID)) == NIL_POINTER)
- ErrorHandler(NO_MENU);
- if ((gEditMenu = GetMHandle(EDIT_MENU_ID)) == NIL_POINTER)
- ErrorHandler(NO_MENU);
-
- AddResMenu(gAppleMenu, 'DRVR');
- DrawMenuBar();
- }
-
- /***************************************************************************\
- * *
- * Routine: TCPInit *
- * *
- * Function: MacTCP initialization. *
- * *
- * Inputs: None *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- TCPInit()
- {
- char tcpDriver[32];
- OSErr openStatus;
-
- strcpy(tcpDriver, ".ipp");
- CtoPstr(tcpDriver);
- openStatus = OpenDriver(&tcpDriver, &TCP_DriverRefNum);
- if (openStatus != noErr)
- {
- strcpy(msgText, "NNTP Server: TCP OpenDriver failed!");
- Report(msgText);
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: CleanUp *
- * *
- * Function: Cleanup between sessions. *
- * *
- * Inputs: None *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- CleanUp()
- {
- TerminateSession(NNTP_PB.tcpStream);
- }
-
- /***************************************************************************\
- * *
- * Routine: HandleEvent *
- * *
- * Function: Handle mouse and keyboard events. *
- * *
- * Inputs: None *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- HandleEvent()
- {
- char theChar;
-
- WaitNextEvent( everyEvent, &gTheEvent, 0L, 0L);
-
- switch ( gTheEvent.what )
- {
- case mouseDown:
- HandleMouseDown();
- break;
- case keyDown:
- case autoKey:
- theChar = gTheEvent.message & charCodeMask;
- if (( gTheEvent.modifiers & cmdKey ) != 0)
- {
- AdjustMenus();
- HandleMenuChoice( MenuKey( theChar ) );
- }
- break;
- case updateEvt:
- break;
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: HandleMouseDown *
- * *
- * Function: Handle mouse events. *
- * *
- * Inputs: None *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- HandleMouseDown()
- {
- WindowPtr whichWindow;
- short int thePart;
- long int menuChoice, windSize;
-
-
- thePart = FindWindow( gTheEvent.where, &whichWindow );
- switch ( thePart )
- {
- case inMenuBar:
- AdjustMenus();
- menuChoice = MenuSelect( gTheEvent.where );
- HandleMenuChoice( menuChoice );
- break;
- case inSysWindow:
- SystemClick( &gTheEvent, whichWindow );
- break;
- case inDrag:
- break;
- case inGoAway:
- break;
- case inContent:
- SelectWindow( whichWindow );
- break;
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: AdjustMenus *
- * *
- * Function: Enable the Edit menu items as necessary. *
- * *
- * Inputs: None *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- AdjustMenus()
- {
- if (IsDAWindow( FrontWindow() ) )
- {
- EnableItem(gEditMenu, UNDO_ITEM );
- EnableItem(gEditMenu, CUT_ITEM );
- EnableItem(gEditMenu, COPY_ITEM );
- EnableItem(gEditMenu, PASTE_ITEM );
- EnableItem(gEditMenu, CLEAR_ITEM );
- }
- else
- {
- DisableItem(gEditMenu, UNDO_ITEM );
- DisableItem(gEditMenu, CUT_ITEM );
- DisableItem(gEditMenu, COPY_ITEM );
- DisableItem(gEditMenu, PASTE_ITEM );
- DisableItem(gEditMenu, CLEAR_ITEM );
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: IsDAWindow *
- * *
- * Function: Determine whether the top window is a Desk Accessory *
- * window. *
- * *
- * Inputs: WindowPtr *
- * *
- * Outputs: TRUE if top window is a Desk Accessory window. *
- * *
- \***************************************************************************/
-
- IsDAWindow( whichWindow )
- WindowPtr whichWindow;
- {
- if ( whichWindow == NIL_POINTER )
- return( FALSE );
- else /* DA windows have negative windowKinds */
- return(((WindowPeek)whichWindow)->windowKind < 0);
- }
-
- /***************************************************************************\
- * *
- * Routine: HandleMenuChoice *
- * *
- * Function: Interpret Menu selections, and call the appropriate *
- * action routines. *
- * *
- * Inputs: Menu choice *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- HandleMenuChoice(menuChoice)
- long int menuChoice;
- {
- int theMenu;
- int theItem;
-
- if (menuChoice != 0)
- {
- theMenu = HiWord(menuChoice);
- theItem = LoWord(menuChoice);
- switch (theMenu)
- {
- case APPLE_MENU_ID :
- HandleAppleChoice( theItem );
- break;
- case FILE_MENU_ID :
- HandleFileChoice(theItem);
- break;
- case EDIT_MENU_ID :
- HandleEditChoice(theItem);
- break;
- }
- HiliteMenu( 0 );
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: HandleAppleChoice *
- * *
- * Function: Interpret Apple Menu selections, and call the appropriate *
- * action routines. *
- * *
- * Inputs: Menu choice *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- HandleAppleChoice(theItem)
- int theItem;
- {
- Str255 accName;
- int accNumber;
-
- switch (theItem)
- {
- case ABOUT_ITEM :
- NoteAlert(ABOUT_ALERT, NIL_POINTER);
- break;
- default :
- GetItem(gAppleMenu, theItem, accName);
- accNumber = OpenDeskAcc(accName);
- break;
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: HandleFileChoice *
- * *
- * Function: Interpret File Menu selections, and call the appropriate *
- * action routines. *
- * *
- * Inputs: Menu choice *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- HandleFileChoice(theItem)
- int theItem;
- {
- WindowPtr whichWindow;
- long finalTicks;
-
- switch ( theItem )
- {
- case RESET_ITEM :
- break;
- case QUIT_ITEM :
- running = FALSE;
- break;
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: HandleEditChoice *
- * *
- * Function: Handle the Edit Menu Choice (only used by DAs) *
- * *
- * Inputs: Menu choice *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- HandleEditChoice(theItem)
- int theItem;
- {
- SystemEdit(theItem - 1);
- }
-
- /***************************************************************************\
- * *
- * Routine: ErrorHandler *
- * *
- * Function: Display a "Stop Alert' *
- * *
- * Inputs: Alert message to be displayed *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- ErrorHandler(stringNum)
- int stringNum;
- {
- StringHandle errorStringH;
-
- if ((errorStringH = GetString( stringNum ) ) == NIL_POINTER)
- ParamText(HOPELESSLY_FATAL_ERROR, NIL_STRING, NIL_STRING, NIL_STRING);
- else
- {
- HLock(errorStringH);
- ParamText(*errorStringH, NIL_STRING, NIL_STRING, NIL_STRING);
- HUnlock(errorStringH);
- }
- StopAlert(ERROR_ALERT_ID, NIL_POINTER);
- ExitToShell();
- }
-
- /***************************************************************************\
- * *
- * Routine: CompletionRtn *
- * *
- * Function: I/O completion routine *
- * *
- * Inputs: None *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- CompletionRtn()
- {
-
- }
-
- /***************************************************************************\
- * *
- * Routine: ReceiveTCP *
- * *
- * Function: TCP recieve routine *
- * *
- * Inputs: Parameter block, buffer, and length *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- ReceiveTCP(pb, buf, length)
- TCPiopb *pb;
- char *buf;
- short length;
-
- {
- OSErr recvStatus;
-
- (*pb).ioCompletion = NIL;
- (*pb).csCode = TCPRcv;
- (*pb).csParam.receive.commandTimeoutValue = 0;
- (*pb).csParam.receive.rcvBuff = buf;
- (*pb).csParam.receive.rcvBuffLen = length;
- (*pb).csParam.receive.userDataPtr = NIL;
- recvStatus = PBControl(pb, TRUE);
- }
-
- /***************************************************************************\
- * *
- * Routine: SendTCP *
- * *
- * Function: TCP send routine *
- * *
- * Inputs: Parameter block, buffer, and length *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- SendTCP(pb, msg, length)
- TCPiopb *pb;
- char *msg;
- short length;
-
- {
- OSErr sendStatus;
-
- (*pb).ioCompletion = NIL;
- (*pb).csCode = TCPSend;
- (*pb).csParam.send.ulpTimeoutValue = 0;
- (*pb).csParam.send.ulpTimeoutAction = 0;
- (*pb).csParam.send.validityFlags = 0x80; /* ULP timeout */
- (*pb).csParam.send.pushFlag = 1; /* Send Immediately */
- (*pb).csParam.send.urgentFlag = 0;
- sendWDS.length1 = length;
- sendWDS.address1 = msg;
- sendWDS.length2 = 0;
- (*pb).csParam.send.wdsPtr = (Ptr) &sendWDS;
- (*pb).csParam.send.userDataPtr = NIL;
- sendStatus = PBControl(pb, TRUE);
- while ((*pb).ioResult == ioInProgress)
- {
- WaitNextEvent(everyEvent, &evt, 0, NIL);
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: PassiveOpen *
- * *
- * Function: TCP passive open routine *
- * *
- * Inputs: Parameter block, TCP port *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- PassiveOpen(pb, port)
- TCPiopb *pb;
- int port;
- {
- OSErr createStatus, passiveStatus;
-
- (*pb).ioCompletion = NIL;
- (*pb).ioCRefNum = TCP_DriverRefNum;
- (*pb).csCode = TCPCreate;
- (*pb).csParam.create.rcvBuff = NewPtr(TCPBufSize);
- (*pb).csParam.create.rcvBuffLen = TCPBufSize;
- (*pb).csParam.create.notifyProc = NIL;
- (*pb).csParam.create.userDataPtr = NIL;
- createStatus = PBControl(pb, FALSE);
-
- (*pb).ioCompletion = NIL;
- (*pb).ioCRefNum = TCP_DriverRefNum;
- (*pb).csCode = TCPPassiveOpen;
- (*pb).csParam.open.ulpTimeoutValue = 0;
- (*pb).csParam.open.ulpTimeoutAction = 0;
- (*pb).csParam.open.validityFlags = 0x80; /* ULP timeout */
- (*pb).csParam.open.commandTimeoutValue = 0;
- (*pb).csParam.open.remoteHost = 0;
- (*pb).csParam.open.remotePort = 0;
- (*pb).csParam.open.localPort = port;
- (*pb).csParam.open.tosFlags = 0x02; /* High Throughput */
- (*pb).csParam.open.dontFrag = 0; /* OK to Fragment */
- (*pb).csParam.open.timeToLive = 64;
- (*pb).csParam.open.security = 0;
- (*pb).csParam.open.optionCnt = 0;
- (*pb).csParam.open.userDataPtr = NIL;
- passiveStatus = PBControl(pb, TRUE);
- }
-
- /***************************************************************************\
- * *
- * Routine: ActiveOpen *
- * *
- * Function: TCP active open routine *
- * *
- * Inputs: Parameter block, TCP local port, TCP remote port *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- ActiveOpen(pb, remHost, locPort, remPort)
- TCPiopb *pb;
- long remHost;
- int locPort, remPort;
- {
- OSErr createStatus, activeStatus;
-
- (*pb).ioCompletion = NIL;
- (*pb).ioCRefNum = TCP_DriverRefNum;
- (*pb).csCode = TCPCreate;
- (*pb).csParam.create.rcvBuff = NewPtr(TCPBufSize);
- (*pb).csParam.create.rcvBuffLen = TCPBufSize;
- (*pb).csParam.create.notifyProc = NIL;
- (*pb).csParam.create.userDataPtr = NIL;
- createStatus = PBControl(pb, FALSE);
-
- (*pb).ioCompletion = NIL;
- (*pb).ioCRefNum = TCP_DriverRefNum;
- (*pb).csCode = TCPActiveOpen;
- (*pb).csParam.open.ulpTimeoutValue = 0;
- (*pb).csParam.open.ulpTimeoutAction = 0;
- (*pb).csParam.open.validityFlags = 0x80; /* ULP timeout */
- (*pb).csParam.open.commandTimeoutValue = 0;
- (*pb).csParam.open.remoteHost = remHost;
- (*pb).csParam.open.remotePort = remPort;
- (*pb).csParam.open.localPort = locPort;
- (*pb).csParam.open.tosFlags = 0x02; /* High Throughput */
- (*pb).csParam.open.dontFrag = 0; /* OK to Fragment */
- (*pb).csParam.open.timeToLive = 64;
- (*pb).csParam.open.security = 0;
- (*pb).csParam.open.optionCnt = 0;
- (*pb).csParam.open.userDataPtr = NIL;
- activeStatus = PBControl(pb, TRUE);
- while ((*pb).ioResult == ioInProgress)
- {
- WaitNextEvent(everyEvent, &evt, 0, NIL);
- }
- if ((*pb).ioResult < 0)
- {
- strcpy(msgText, "NNTP Server: TCP Active Open failed!");
- Report(msgText);
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: RecieveStatus *
- * *
- * Function: Check the status of a TCP recieve, and report an *
- * error if there was a problem. *
- * *
- * Inputs: Parameter block *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- RecieveStatus(pb)
- TCPiopb *pb;
- {
- while ((*pb).ioResult == ioInProgress)
- {
- WaitNextEvent(everyEvent, &evt, 0, NIL);
- }
- if ((*pb).ioResult < 0)
- {
- strcpy(msgText, "NNTP Server: TCP Receive failed!");
- Report(msgText);
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: SendStatus *
- * *
- * Function: Check the status of a TCP send, and report an *
- * error if there was a problem. *
- * *
- * Inputs: Parameter block *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- SendStatus(pb)
- TCPiopb *pb;
- {
- while ((*pb).ioResult == ioInProgress)
- {
- WaitNextEvent(everyEvent, &evt, 0, NIL);
- }
- if ((*pb).ioResult < 0)
- {
- strcpy(msgText, "NNTP Server: TCP Send failed!");
- Report(msgText);
- }
- }
-
- /***************************************************************************\
- * *
- * Routine: TerminateSession *
- * *
- * Function: Shut down a TCP connection, and release the stream. *
- * *
- * Inputs: Stream *
- * *
- * Outputs: None *
- * *
- \***************************************************************************/
-
- TerminateSession(stream)
- StreamPtr stream;
- {
- OSErr releaseStatus, status;
- TCPiopb pb;
- TCPiopb statusPB;
-
- /* Wait for transmitted data to complete. */
-
- status = noErr;
- statusPB.csParam.status.amtUnackedData = -1;
- while((statusPB.csParam.status.amtUnackedData != 0) && (status == noErr))
- {
- statusPB.ioCompletion = NIL;
- statusPB.ioCRefNum = TCP_DriverRefNum;
- statusPB.tcpStream = stream;
- statusPB.csCode = TCPStatus;
- status = PBControl(&statusPB, FALSE);
- WaitNextEvent( everyEvent, &gTheEvent, 0L, 0L);
- }
-
- /* Close the connection. */
-
- pb.ioCompletion = NIL;
- pb.ioCRefNum = TCP_DriverRefNum;
- pb.tcpStream = stream;
- pb.csCode = TCPClose;
- releaseStatus = PBControl(&pb, TRUE);
- while (pb.ioResult == inProgress)
- {
- WaitNextEvent( everyEvent, &gTheEvent, 0L, 0L);
- }
-
- /* Wait for the close to complete. */
-
- statusPB.csParam.status.connectionState = ESTABLISHED;
- status = noErr;
- while((statusPB.csParam.status.connectionState != CLOSED) && (status == noErr))
- {
- statusPB.ioCompletion = NIL;
- statusPB.ioCRefNum = TCP_DriverRefNum;
- statusPB.tcpStream = stream;
- statusPB.csCode = TCPStatus;
- status = PBControl(&statusPB, FALSE);
- WaitNextEvent( everyEvent, &gTheEvent, 0L, 0L);
- }
-
- /* Release the stream. */
-
- pb.ioCompletion = NIL;
- pb.ioCRefNum = TCP_DriverRefNum;
- pb.tcpStream = stream;
- pb.csCode = TCPRelease;
- releaseStatus = PBControl(&pb, FALSE);
- }
-
- /***************************************************************************\
- * *
- * Routine: TCPStatusCheck *
- * *
- * Function: Determine the state of a connection. *
- * *
- * Inputs: Stream *
- * *
- * Outputs: Connection state (see MacTCP documentation). *
- * *
- \***************************************************************************/
-
- TCPStatusCheck(stream)
- StreamPtr stream;
- {
- OSErr status;
- TCPiopb statusPB;
-
- statusPB.ioCompletion = NIL;
- statusPB.ioCRefNum = TCP_DriverRefNum;
- statusPB.tcpStream = stream;
- statusPB.csCode = TCPStatus;
- status = PBControl(&statusPB, FALSE);
- return statusPB.csParam.status.connectionState;
- }
-
- /***************************************************************************\
- * *
- * Routine: Report *
- * *
- * Function: Use the Notification Manager to report an error. *
- * *
- * Inputs: Error message. *
- * *
- * Outputs: Dialog box display. *
- * *
- \***************************************************************************/
-
- Report(Err)
- char *Err;
- {
- OSErr nmStatus;
- NMRecPtr errorNotification;
- Ptr sP;
-
- errorNotification = (NMRecPtr) NewPtr(sizeof(NMRec));
- (*errorNotification).qType = 8;
- (*errorNotification).nmMark = 0;
- (*errorNotification).nmIcon = NIL;
- (*errorNotification).nmSound = (Handle) -1;
- sP = NewPtr(MaxErrorString);
- strcpy(sP, Err);
- CtoPstr(sP);
- (*errorNotification).nmStr = (StringPtr) sP;
- (*errorNotification).nmResp = (ProcPtr) -1;
- (*errorNotification).nmRefCon = 0;
-
- nmStatus = NMInstall(errorNotification);
-
- }
-
- /***************************************************************************\
- * *
- * Routine: GetWord *
- * *
- * Function: Parse out a word from a line of text seperated by white *
- * space (space, tab, <CR>, <LF>). *
- * *
- * Inputs: Input buffer, result buffer, word number. *
- * *
- * Outputs: Result word. *
- * *
- \***************************************************************************/
-
- GetWord(buf, word, whichWord)
- char *buf, *word;
- short whichWord;
- {
- char *src, *dst;
- short skip;
-
- src = buf;
- dst = word;
- skip = whichWord -1;
- while (skip > 0)
- {
- while ((*src == SPACE) || (*src == TAB)) /* Skip to a word. */
- {
- src++;
- }
- while ((*src != SPACE) && (*src != TAB)) /* Skip the word. */
- {
- src++;
- }
- skip--;
- }
- while ((*src == SPACE) || (*src == TAB)) /* Skip to start of word. */
- {
- src++;
- }
- while ((*src != SPACE) && (*src != TAB) /* Copy the word. */
- && (*src != CR) && (*src != LF) && (*src != 0))
- {
- *dst++ = *src++;
- }
- *dst++ = 0;
- }
-
-
-
-